<?php
if (!class_exists('Picture', false)) {
    /**
     * 图片下载处理
     *
     * @author Akon(番茄红了) <aultoale@gmail.com>
     */
    class Picture
    {

        /**
         * 临时文件目录
         *
         * @var string
         */
        public static $tmppath = null;

        /**
         * 文件保存路径
         *
         * @var string
         */
        public static $savepath = null;

        /**
         * md5 目录级数
         *
         * @var int
         */
        public static $md5level = 2;

        /**
         * 下载次数限制
         *
         * @var int
         */
        public static $success = 100;


        /**
         * 变量初始化
         *
         * @param   none
         * @access  public
         * @return  void
         * @update  date time
        */
        public static function set_variable()
        {
            // 文件保存路径
            Picture::$savepath = IO::strip(RESPATH.'/product');
            Picture::$tmppath = IO::mkdir(Picture::$savepath.'/temp');
            Picture::$md5level = 2; // 1级目录支持约10万左右图片，2级支持约1000万左右图片

            Picture::$success = 100;

        } // end func

        /**
         * 获取远程图片信息
         *
         * @param  string  $url
         * @return string  临时文件
         */
        public static function remoteImage($url)
        {
            // 生成图片地址
            $url = 'http://img0'.mt_rand(1, 8).'.taobaocdn.com/bao/uploaded/'.$url;

            // 下载图片数据
            $imgData = false;
            for ($i = 0; $i < 5; $i++) {
                $imgData = @file_get_contents($url);
                if ($imgData !== false) {
                    break;
                }
                sleep(5); // 休息5秒
            }

            // 写入临时文件
            $tmpfile = false;
            if ($imgData !== false) {
                $tmpfile = self::$tmppath.'/'.basename($url);
                if (!is_file($tmpfile)) {
                    file_put_contents($tmpfile, $imgData);
                }
            }

            return $tmpfile;
        }

        /**
         * 保存临时文件
         *
         * @param  string  $tmpfile
         * @return string  保存后的文件名
         */
        public static function saveImage($tmpfile)
        {
            // 获取 md5 值
            $md5 = md5_file($tmpfile);

            // 生成 md5 路径
            $local = 0; $md5path = '';
            for ($i = 0; $i < self::$md5level; $i++)
            {
                $md5path .= '/'.substr($md5, $local, 2);
                $local += 2;
            }

            // 创建目录
            $savepath = IO::mkdir(self::$savepath.$md5path);

            // 存储路径及文件名
            $savefile = $savepath.'/'.$md5.strtolower(strrchr($tmpfile, '.'));

            // 重命名临时文件
            if (!is_file($savefile)) {
                $rename = @rename($tmpfile, $savefile);
                if (!$rename) {
                    return false;
                }
            }

            return $savefile;
        }


        /**
         * 下载“products”表图片
         *
         * @param   none
         * @access  public
         * @return  void
         * @update  2011/3/29
        */
        public static function download_products()
        {
            // 获取数量统计
            $total = DB::select(DB::expr('COUNT(*)'))
                ->from('products')
                ->where('pic_url', '!=', '')
                ->where('image_md5', '=', '')
                ->fetch_one();
            $success = self::$success;
            do {
                if ($total == 0 || $success - 100 >= $total)
                {
                    break;
                }
                // 取出未下载的产品数据
                $rows = DB::select('product_id', 'pic_url')
                    ->from('products')
                    ->where('pic_url', '!=', '')
                    ->where('image_md5', '=', '')
                    ->order_by(DB::expr('RAND()'))
                    ->limit(100)
                    ->fetch_all();
                if (count($rows) == 0)
                {
                    break;  // 数据为空，返回
                }
                foreach ($rows as $row)
                {
                    // 获取图片信息
                    $tmpfile = Picture::remoteImage($row['pic_url']);
                    if ($tmpfile !== false)
                    {
                        // 获取 md5 值
                        if ($savefile = Picture::saveImage($tmpfile))
                        {
                            DB::update('products')->set(array('image_md5' => basename($savefile)))->where('product_id', '=', $row['product_id'])->execute();
                            echo ">";
                        } else {
                            echo "|";
                        }
                    } else {
                        echo ".";
                        DB::update('products')->set(array('pic_url' => ''))->where('product_id', '=', $row['product_id'])->execute();
                    }
                    @unlink($tmpfile); // 删除临时文件
                    $success++;
                }
            } while (true);

        } // end func


        /**
         * 下载“product_imgs”表图片
         *
         * @param   none
         * @access  public
         * @return  void
         * @update  2011/3/29
        */
        public static function download_products_imgs()
        {
            // 获取数量统计
            $total = DB::select(DB::expr('COUNT(*)'))
                ->from('product_imgs')
                ->where('pic_url', '!=', '')
                ->where('image_md5', '=', '')
                ->fetch_one();
            $success = self::$success;
            do {

                if ($total == 0 || $success - 100 >= $total)
                {
                    break;
                }

                CLI::output("\n[$success/$total ".round($success/$total*100,1)."%] ");

                // 取出未下载的产品数据
                $rows = DB::select('id', 'url')
                    ->from('product_imgs')
                    ->where('url', '=', '')
                    ->where('image_md5', '=','')
                    ->order_by(DB::expr('RAND()'))
                    ->limit(100)
                    ->fetch_all();

                // 数据为空，返回
                if (count($rows) == 0)
                {
                    break;
                }

                foreach ($rows as $row)
                {
                    // 获取图片信息
                    $tmpfile = Picture::remoteImage($row['url']);
                    if ($tmpfile !== false)
                    {
                        // 获取 md5 值
                        $savefile = Picture::saveImage($tmpfile);
                        // 更新数据库
                        $savefile && DB::update('product_imgs')->set(array('image_md5' => basename($savefile)))->where('id', '=', $row['id'])->execute();
                        echo ">";
                    } else {
                        echo ".";
                    }
                    @unlink($tmpfile); // 删除临时文件
                    $success++;
                }

            } while(true );
        } // end func



        /**
         * 同步products图片
         *
         * @param   none
         * @access  public
         * @return  void
         * @update  2011/3/29
        */
        public static function merge_products()
        {
            DB::query(Database::UPDATE, 'ALTER TABLE `product_imgs` AUTO_INCREMENT=20000000')->execute();

            $total = DB::select(DB::expr('COUNT(*)'))
                ->from('products')
                ->where('image_md5', '<>','')
                ->fetch_one();

            echo "\n";

            $limit = 100;
            for ($offset = 0; $offset < $total; $offset += $limit)
            {
                $rows = DB::select()
                    ->from('products')
                    ->where('image_md5', '<>', '')
                    ->order_by('product_id','asc')
                    ->limit($limit)
                    ->offset($offset)
                    ->fetch_all();
                foreach ($rows as $row)
                {
                    // 查询product_imgs表
                    $found = (bool) DB::select(DB::expr('COUNT(0)'))
                        ->from('product_imgs')
                        ->where('product_id','=', $row['product_id'])
                        ->where('image_md5', '=', $row['image_md5'])
                        ->fetch-one();
                    if (! $found)
                    {
                        $data = array(
                            'product_id' => $row['product_id'],
                            'url' => $row['pic_url'],
                            'image_md5' => $row['image_md5'],
                            'position' => 0,
                            'created' => time(),
                            'modified' => time(),
                        );
                        DB::insert('product_imgs', array_keys($data))->values(array_values($data))->execute();
                    }
                }
                echo ">";
            }
        } // end func



        /**
         * 同步所有产品图片
         *
         * @param   none
         * @access  public
         * @return  void
         * @update  2011/3/29
        */
        public function main()
        {
            // 设置变量
            Picture::set_variable();
            // 下载产品表图片
            Picture::download_products();
            // 下载产品图片表图片
            Picture::download_products_imgs();
            // 同步图片
            Picture::merge_products();
        } // end func
    }
}

// 同步图片开始
Picture::sync_pictures();


/**
 * 下载图片数据
 *
 * @author Akon(番茄红了) <aultoale@gmail.com>


$picsMenu = <<<EOF

---------------------------

 1、下载“products”表图片

 2、下载“product_imgs”表图片

 3、下载“product_prop_imgs”表图片

 4、同步“product_imgs”表图片

 0、返回

---------------------------

请选择 (0,1,2,3,4)：
EOF;

do {
    // 显示菜单
    $input = CLI::input($picsMenu);

    // 文件保存路径
    Picture::$savepath = TRUNK_PATH.'/resources/product';
    Picture::$tmppath = EGP_Io::mkdir(Picture::$savepath.'/temp');
    Picture::$md5level = 2; // 1级目录支持约10万左右图片，2级支持约1000万左右图片

    $success = 100;

    // 下载“products”表图片
    if ($input == 1) {

        // 获取数量统计
        $total = DB::select()
            ->from('products', DB::expr('COUNT(*)'))
            ->where('pic_url IS NOT NULL')
            ->where('image_md5 IS NULL')
            ->fetchOne();

        CLI::output("\n准备开始下载，共 $total 条记录...\n");

        do {

            if ($total == 0 || $success - 100 >= $total) {
                break;
            }

            CLI::output("\n[$success/$total ".round($success/$total*100,1)."%] ");

            // 取出未下载的产品数据
            $rows = DB::select()
                ->from('products', array('product_id', 'pic_url'))
                ->where('pic_url IS NOT NULL')
                ->where('image_md5 IS NULL')
                ->order(DB::expr('RAND()'))
                ->limit(100)
                ->fetchAll();
            if (count($rows) == 0) {
                break;  // 数据为空，返回
            }

            foreach ($rows as $row) {
                // 获取图片信息
                $tmpfile = Picture::remoteImage($row['pic_url']);
                if ($tmpfile !== false) {
                    // 获取 md5 值
                    if ($savefile = Picture::saveImage($tmpfile)) {
                        DB::update('products', array('image_md5' => basename($savefile)), 'product_id='.$row['product_id']);
                        echo ">";
                    } else {
                        echo "|";
                    }
                } else {
                    echo ".";
                    DB::update('products', array('pic_url' => ''), 'product_id='.$row['product_id']);
                }
                @unlink($tmpfile); // 删除临时文件
                $success++;
            }

        } while(true );

        CLI::output("\n\n“product_imgs”表图片下载完成...\n");

    // 下载“product_imgs”表图片
    } elseif ($input == 2) {

        // 获取数量统计
        $total = DB::select()
            ->from('product_imgs', DB::expr('COUNT(*)'))
            ->where('url IS NOT NULL')
            ->where("image_md5=''")
            ->fetchOne();

        CLI::output("\n准备开始下载，共 $total 条记录...\n");

        do {

            if ($total == 0 || $success - 100 >= $total) {
                break;
            }

            CLI::output("\n[$success/$total ".round($success/$total*100,1)."%] ");

            // 取出未下载的产品数据
            $rows = DB::select()
                ->from('product_imgs', array('id', 'url'))
                ->where('url IS NOT NULL')
                ->where("image_md5=''")
                ->order(DB::expr('RAND()'))
                ->limit(100)
                ->fetchAll();
            if (count($rows) == 0) {
                break;  // 数据为空，返回
            }

            foreach ($rows as $row) {
                // 获取图片信息
                $tmpfile = Picture::remoteImage($row['url']);
                if ($tmpfile !== false) {
                    // 获取 md5 值
                    $savefile = Picture::saveImage($tmpfile);
                    // 更新数据库
                    $savefile && DB::update('product_imgs', array('image_md5' => basename($savefile)), 'id='.$row['id']);
                    echo ">";
                } else {
                    echo ".";
                }
                @unlink($tmpfile); // 删除临时文件
                $success++;
            }

        } while(true );

        CLI::output("\n\n“product_imgs”表图片下载完成...\n");

    // 下载“product_prop_imgs”表图片
    } elseif ($input == 3) {

        // 获取数量统计
        $total = DB::select()
            ->from('product_prop_imgs', DB::expr('COUNT(*)'))
            ->where('url IS NOT NULL')
            ->where('image_md5 IS NULL')
            ->fetchOne();

        CLI::output("\n准备开始下载，共 $total 条记录...\n");

        do {

            if ($total == 0 || $success - 100 >= $total) {
                break;
            }

            CLI::output("\n[$success/$total ".round($success/$total*100,1)."%] ");

            // 取出未下载的产品数据
            $rows = DB::select()
                ->from('product_prop_imgs', array('id', 'url'))
                ->where('url IS NOT NULL')
                ->where('image_md5 IS NULL')
                ->order(DB::expr('RAND()'))
                ->limit(100)
                ->fetchAll();
            if (count($rows) == 0) {
                break;  // 数据为空，返回
            }

            foreach ($rows as $row) {
                // 获取图片信息
                $tmpfile = Picture::remoteImage($row['url']);
                if ($tmpfile !== false) {
                    // 获取 md5 值
                    $savefile = Picture::saveImage($tmpfile);
                    // 更新数据库
                    $savefile && DB::update('product_prop_imgs', array('image_md5' => basename($savefile)), 'id='.$row['id']);
                    echo ">";
                } else {
                    echo ".";
                }
                @unlink($tmpfile); // 删除临时文件
                $success++;
            }

        } while(true );

        CLI::output("\n\n“product_prop_imgs”表图片下载完成...\n");

    // 同步products图片
    } elseif ($input == 4) {

        DB::query('ALTER TABLE `product_imgs` AUTO_INCREMENT=20000000');

        $total = DB::select()
            ->from('products', DB::expr('COUNT(*)'))
            ->where("image_md5<>''")
            ->fetchOne();

        echo "\n";

        $limit = 100;
        for ($offset = 0; $offset < $total; $offset += $limit) {
            $rows = DB::select()
                ->from('products')
                ->where("image_md5<>''")
                ->order('product_id ASC')
                ->limit($limit, $offset)
                ->fetchAll();
            foreach ($rows as $row) {
                // 查询product_imgs表
                $found = (bool) DB::select()
                    ->from('product_imgs', DB::expr('COUNT(0)'))
                    ->where('product_id=?', $row['product_id'])
                    ->where('image_md5=?', $row['image_md5'])
                    ->fetchOne();
                if (! $found) {
                    $data = array(
                        'product_id' => $row['product_id'],
                        'url' => $row['pic_url'],
                        'image_md5' => $row['image_md5'],
                        'position' => 0,
                        'created' => time(),
                        'modified' => time(),
                    );
                    DB::insert('product_imgs', $data);
                }
            }
            echo ">";
        }

        CLI::output("\n\n“products”表图片数据同步完成...\n");

    // 返回
    } else {
        break;
    }

    CLI::input("\n请按下回车键继续！");

} while (true);

unset($picsMenu);
 */